/* Copyright (c) 2004-2022 peigen.info. All rights reserved. */
package info.peigen.hotpot.common.core.enums;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <b>(YesOrNo)</b>
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2021/4/18
 */
@Getter
@NoArgsConstructor
@AllArgsConstructor
public enum YesOrNo implements Messageable {
    /** 为了对抗 Alibaba Java Coding 而存在的注释 */
    Y, N;

    /** 枚举值 */
    private String code;

    /** 枚举描述 */
    private String message;

    public static String whether(YesOrNo yesOrNo) {
        return yesOrNo == Y ? "是" : "否";
    }

    /**
     * 获取一个随机枚举
     *
     * @return YesOrNo
     */
    public static YesOrNo getRandomEnum() {
        return RandomUtil.randomEle(Stream.of(values()).toList());
    }

    /**
     * 获取一个随机枚举
     *
     * @param ignores 忽略几个枚举
     *
     * @return YesOrNo
     */
    public static YesOrNo getRandomEnum(YesOrNo... ignores) {
        return RandomUtil.randomEle(Stream.of(values()).filter(v -> !CollUtil.contains(Arrays.asList(ignores), v)).toList());
    }

    /**
     * 通过枚举<code>code</code>获得枚举
     *
     * @param code code
     *
     * @return YesOrNo
     */
    public static YesOrNo getByCode(String code) {
        return Stream.of(values())
                .filter(innerEnum -> StrUtil.equals(code, innerEnum.name()))
                .findFirst().orElse(null);
    }

    /**
     * 获取全部枚举
     *
     * @return List<YesOrNo>
     */
    public static List<YesOrNo> getAllEnum() {
        return Lists.newArrayList(values());
    }

    /**
     * 获取全部枚举值
     *
     * @return List<String>
     */
    public static List<String> getAllEnumCode() {
        return getAllEnum().stream().map(Enum::name).collect(Collectors.toList());
    }

    /**
     * 通过code获取msg
     *
     * @param code 枚举值
     *
     * @return String
     */
    public static String getMsgByCode(String code) {

        return Optional.ofNullable(code).flatMap(str -> Optional.ofNullable(getByCode(str))
                .map(YesOrNo::name)).orElse(null);
    }

    /**
     * 获取枚举code
     *
     * @param innerEnum enum
     *
     * @return String
     */
    public static String getCode(YesOrNo innerEnum) {
        return Optional.ofNullable(innerEnum).map(Enum::name).orElse(null);
    }

    /**
     * 实名登记map
     *
     * @return Map
     */
    public static Map<String, String> maps() {

        return Stream.of(values()).collect(Collectors.toMap(YesOrNo::name, YesOrNo::name));
    }

    /** @return Returns the code. */
    @Override
    public String code() {
        return name();
    }

    /** @return Returns the message. */
    @Override
    public String message() {
        return name();
    }
}